"""
用户逻辑处理模块

"""
from flask import g, session
from flask_login import current_user
from playhouse.shortcuts import model_to_dict

from apps.models.sdn import Vll
# from apps.controller.common import get_menu_info
from apps.models.user import User, UserRole, UserRolePermission, Permission, Role, UserOrg
from apps.utils.views import resp_with_data, get_page
from components.base_exception import *
from components.base_log import log_method_call


@log_method_call(action='Retrieve')
def get_user():
    """
    处理获取用户
    """
    conditions = [User.is_del == False, UserOrg.org_id << g.real_org_ids]
    if getattr(g, 'search_name', None):
        conditions.append(User.name ** ('%{}%'.format(g.search_name)))
    if getattr(g, 'search_phone', None):
        conditions.append(User.phone ** ('%{}%'.format(g.search_phone)))
    if hasattr(g, 'search_status'):
        if g.search_status:
            conditions.append(User.enable == g.search_status)
        else:
            conditions.append(User.enable << [True, False])
    data = {'items': []}
    query = User.select(User).join_from(User, UserOrg).where(*conditions)
    if g.page:
        data['page'] = get_page(query)
        query = query.paginate(g.page, g.per_page)
    for user in query:
        data['items'].append(user.get_standard_obj())
    return data


@log_method_call(action='Retrieve')
def get_menu(parent_id=None, ids=None):
    """
    处理menu
    """
    if ids:
        permissions = Permission.select().where(Permission.type << [1, 2],
                                                Permission.parent_id == parent_id,
                                                Permission.id << ids,
                                                Permission.is_del == False)
    else:
        permissions = Permission.select().where(Permission.type << [1, 2],
                                                Permission.parent_id == parent_id,
                                                Permission.is_del == False)
    menus = []
    for permission in permissions:
        menu = model_to_dict(permission, only=[Permission.id,
                                               Permission.name,
                                               Permission.parent,
                                               Permission.path,
                                               Permission.visible,
                                               Permission.component,
                                               Permission.component_name,
                                               Permission.icon,
                                               Permission.type])
        menu['componentName'] = menu['component_name']
        menu['parentId'] = menu['parent']['id'] if menu['parent'] else ''
        del menu['parent']
        del menu['component_name']
        children = get_menu(parent_id=permission.id)
        if children:
            menu['children'] = children
        else:
            menu['children'] = None
        menus.append(menu)
    return menus


@log_method_call(action='Retrieve')
def get_permission(permission_ids):
    """
    处理按钮及权限code
    """
    permission_list = []
    permissions = Permission.select().where(Permission.id << permission_ids, Permission.type == 3)
    for permission in permissions:
        if permission.enable and permission.code:
            permission_list.append(permission.code)
    return permission_list


@log_method_call(action='Retrieve')
def get_user_info():
    """
    处理获取用户详情
    """
    # 查询
    data = dict()
    user = User.get_or_none(id=g.user_id)
    user_roles = UserRole.select(UserRole.role_id).where(UserRole.user_id == g.user_id)
    role_ids = [role.role_id for role in user_roles]
    user_permission = UserRolePermission.select().where(UserRolePermission.role_id << role_ids)
    permission_ids = list(set([permission.permission_id for permission in user_permission]))
    menu = get_menu(ids=permission_ids)
    permission_list = get_permission(permission_ids)
    data['menus'] = menu
    data['permissions'] = permission_list
    data['user'] = user.get_standard_obj()
    data['roles'] = data['user']['roles']
    return data


@log_method_call(action='Retrieve')
def get_member_info(pk):
    """
    处理获取用户详情
    """
    # 查询
    data = dict()
    user = User.get_or_none(id=pk)
    user_roles = UserRole.select(UserRole.role_id).where(UserRole.user_id == g.user_id)
    role_ids = [role.role_id for role in user_roles]
    user_permission = UserRolePermission.select().where(UserRolePermission.role_id << role_ids)
    permission_ids = list(set([permission.permission_id for permission in user_permission]))
    menu = get_menu(ids=permission_ids)
    permission_list = get_permission(permission_ids)
    data['menus'] = menu
    data['permissions'] = permission_list
    data['user'] = user.get_standard_obj()
    data['roles'] = data['user']['roles']

    return data


@log_method_call(action='Update')
def update_user_for_org():
    """
    处理更新用户
    """
    user = User.get_or_none(id=g.json.get('id'))
    if not user:
        raise NotFoundError()
    user.email = g.json.get('email')
    user.sex = g.json.get('sex')
    user.name = g.json.get('name')
    user.position = g.json.get('position')
    user.is_receive_email = g.json.get('is_receive_email')
    user.save()
    return user.get_standard_obj()


@log_method_call(action='Create')
def add_user_for_org():
    """
    处理添加用户
    """
    user = User.create(
        name=g.json.get('name'),
        phone=g.json.get('phone'),
        email=g.json.get('email'),
        sex=g.json.get('sex') if g.json.get('sex') else 1,
        position=g.json.get('position'),
        is_receive_email=g.json.get('is_receive_email') if g.json.get('is_receive_email') else True,
    )
    for role in g.json.get('role_ids'):
        UserRole.create(
            role_id=role,
            user_id=user.id
        )
    for org_id in g.json.get('org_id'):
        UserOrg.create(
            user_id=user.id,
            org_id=org_id
        )
    return user.get_standard_obj()


@log_method_call(action='Update')
def update_logo_for_user(logo_path):
    user = User.get_or_none(User.id == g.user_id)
    user.avatar = logo_path
    user.save()


@log_method_call(action='Update')
def user_enable_status(status=True):
    """
    处理用户禁用启用
    """
    user = User.get_or_none(User.id == g.json.get('user_id'))
    if status:
        user.enable = True
    else:
        user.enable = False
    user.save()
    return model_to_dict(user)


@log_method_call(action='Update')
def user_delete_status():
    """
    处理用户禁用启用
    """
    user = User.get_or_none(User.id == g.json.get('user_id'))
    user.is_del = True
    user.save()
    return model_to_dict(user)


@log_method_call(action='Retrieve')
def get_user_auth():
    """
    处理用户权限
    """
    data = {'items': []}
    user_roles = UserRole.select().where(UserRole.user_id == g.json.get('user_id'))
    for user_role in user_roles:
        permissions = UserRolePermission.select().where(UserRolePermission.role_id == user_role.role_id)
        for permission in permissions:
            if permission.permission.code and permission.permission.enable:
                if permission.permission not in data['items']:
                    data['items'].append(model_to_dict(permission.permission))
    return data


@log_method_call(action='Update')
def update_user_auth():
    """
    处理更新权限
    逻辑:
        示例:
        code  [1, 2, 3, 4, 6]
        permission [1, 2, 3, 4, 5]
        1. 获取到最新的code表
        2. 查询code所在的permission表的id
        3. 通过传的userid获取到当前角色的permission表
        4. code表和permission表进行对比
        list(set(code).difference(set(permission)))  代表需要新增的权限
        list(set(permission).difference(set(code)))  代表需要删除的权限
    """
    code_list = g.json.get('code_list')
    user_role = UserRole.get_or_none(UserRole.user_id == g.json.get('user_id'))
    permissions = UserRolePermission.select().where(UserRolePermission.role_id == user_role.role_id)
    permission = {auth.id: auth.permission.code for auth in permissions}
    need_del = list(set(list(permission.values())).difference(set(code_list)))
    need_add = list(set(code_list).difference(set(list(permission.values()))))
    for code in need_del:
        need_del_id = list(filter(lambda x: permission[x] == code, permission))[0]
        res = UserRolePermission.get_or_none(UserRolePermission.id == need_del_id)
        res.delete_instance()
    codes = Permission.select().where(Permission.code << need_add)
    for code in codes:
        UserRolePermission.create(
            role_id=user_role.role_id,
            permission_id=code.id
        )
